home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
exampleCode
/
opengl
/
glx
/
util.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
9KB
|
340 lines
/*
* Copyright (C) 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* 1993 Simon Hui -- Silicon Graphics Computer Systems
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <X11/keysym.h>
#include "util.h"
static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
{
if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
return GL_TRUE;
}
return GL_FALSE;
}
Window utilCreateWindow( int defW, int defH, int defX, int defY, Window parent,
int attributes[], char *colorName,
int argc, char **argv, char *geometry,
Display **dpy_ret, XVisualInfo **vi_ret,
Colormap *cmap_ret, GC *xgc_ret )
{
Display *dpy;
Window window;
XVisualInfo *vi;
Colormap cmap;
GC xgc;
XSetWindowAttributes swa;
unsigned int width, height;
XGCValues gcvalues;
XColor xcolor, exact;
XSizeHints sh;
XEvent event;
if (dpy_ret && *dpy_ret) {
dpy = *dpy_ret;
} else {
dpy = XOpenDisplay(0);
if (!dpy) {
fprintf(stderr, "Can't connect to display \"%s\"\n",
getenv("DISPLAY"));
exit(1);
}
}
vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributes);
if (!vi) {
fprintf(stderr, "Cannot find visual on \"%s\"\n",
getenv("DISPLAY"));
exit(1);
}
if (cmap_ret && *cmap_ret) {
cmap = *cmap_ret;
} else {
cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
AllocNone);
}
if (colorName) {
if (!XAllocNamedColor(dpy, cmap, colorName, &exact, &xcolor)) {
fprintf(stderr, "Can't allocate color %s for X\n", colorName);
exit(1);
}
swa.background_pixel = xcolor.pixel;
} else {
swa.background_pixel = 0;
}
swa.border_pixel = 0;
swa.colormap = cmap;
swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
| KeyReleaseMask;
width = defW;
height = defH;
sh.x = defX;
sh.y = defY;
if (geometry) {
int x, y;
unsigned int w, h;
int mask = XParseGeometry(geometry, &x, &y, &w, &h);
if (mask & XValue) sh.x = x;
if (mask & YValue) sh.y = y;
if (mask & WidthValue) width = w;
if (mask & HeightValue) height = h;
}
sh.flags = USPosition | PPosition;
if (parent == None) parent = RootWindow(dpy, vi->screen);
window = XCreateWindow(dpy, parent, sh.x, sh.y,
width, height,
0, vi->depth, InputOutput, vi->visual,
CWBorderPixel|CWColormap|CWEventMask|CWBackPixel,
&swa);
XSetStandardProperties(dpy, window, argv[0], argv[0],
None, argv, argc, &sh);
XSetWMColormapWindows(dpy, window, &window, 1);
XMapWindow(dpy, window);
XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
if (!xgc_ret || !*xgc_ret) {
gcvalues.background = xcolor.pixel;
gcvalues.foreground = xcolor.pixel;
xgc = XCreateGC(dpy, window, GCForeground|GCBackground, &gcvalues);
}
if (dpy_ret) *dpy_ret = dpy;
if (vi_ret) *vi_ret = vi;
if (cmap_ret) *cmap_ret = cmap;
if (xgc_ret) *xgc_ret = xgc;
return window;
}
void utilEventLoop( Display *dpy,
void (*exposeCallback)(void),
void (*keyCallback)( KeySym, Bool *exit, Bool *redraw),
void (*displayCallback)(void) )
{
XEvent event;
Bool redraw = False;
for (;;) {
do {
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
if (exposeCallback) {
(*exposeCallback)();
} else {
(*displayCallback)();
}
break;
case KeyPress:
{
char buf[100];
int rv;
KeySym ks;
Bool exit = False;
rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
(*keyCallback)(ks, &exit, &redraw);
if (exit) return;
}
break;
}
} while (XPending(dpy) != 0);
if (redraw) {
(*displayCallback)();
redraw = False;
}
}
}
/*------ routines for prompting user ---------------------------------------*/
void utilPromptUser( void )
{
char buf[20];
printf( "Hit return for next frame: ");
gets(buf);
}
/*------ routines for reading images ---------------------------------------*/
#include <gl/image.h>
void utilDumpRGBImage( char *fname, int width, int height, char *buf )
{
IMAGE *image;
int sz=width*height*3;
int x, y, i;
short *rbuf, *gbuf, *bbuf;
char fullname[40];
sprintf( fullname, "%s.img", fname );
if ((image=iopen( fullname, "w", RLE(1), 3, width, height, 3)) == NULL) {
fprintf(stderr,"iopen: can't open input file %s", fullname);
exit(1);
}
rbuf = (short *)malloc(width*sizeof(short));
gbuf = (short *)malloc(width*sizeof(short));
bbuf = (short *)malloc(width*sizeof(short));
for (y=0; y < height; y++) {
for (x=0; x < width; x++) {
i = (y*width + x)*3;
rbuf[x] = buf[i];
gbuf[x] = buf[i+1];
bbuf[x] = buf[i+2];
}
putrow( image, rbuf, y, 0 );
putrow( image, gbuf, y, 1 );
putrow( image, bbuf, y, 2 );
}
iclose( image );
free( rbuf );
free( gbuf );
free( bbuf );
}
void write_asc_file( char *fname, int width, int height, unsigned char *buf )
{
FILE *fp;
int sz=width*height*3;
int x, y, i, n;
char fullname[40];
unsigned long p;
sprintf( fullname, "%s.asc", fname );
if (!(fp = fopen( fullname, "w"))) {
fprintf(stderr,"fopen: can't open input file %s", fullname);
exit(1);
}
n = 0;
for (y=0; y < height; y++) {
fprintf( fp, "\nline %2d\n", y );
for (x=0; x < width; x++) {
i = (y*width + x)*3;
p = buf[i+2];
p <<= 8;
p |= buf[i+1];
p <<= 8;
p |= buf[i];
fprintf (fp, "%8x ", p);
n++;
if (!(n % 8)) fprintf( fp, "\n" );
}
}
fclose( fp );
}
/*---- Find graphics board type (stolen from ogtst) ----------------------*/
void utilGetGraphicsName( char *glrenderer, char *buf )
{
char a[32],b[32],c[32],d[32];
/* REALITY ENGINE/VTX */
if (!strncmp("RE", glrenderer, 2) || !strncmp("VTX", glrenderer, 3)) {
sscanf(glrenderer,"%[^/]%*c%[^/]%*c%[^/]%*c%1s",a,b,c,d);
strcpy(buf, "RE");
strcat(buf, c);
}
/* EXPRESS */
else if (!strncmp("GR2-Elan", glrenderer, 8) ||
!strncmp("GR2EV-Extreme", glrenderer, 13) ||
!strncmp("GU1-Extreme", glrenderer, 11) ||
!strncmp("GR2-XZ", glrenderer, 6)) {
strcpy(buf, "XG24");
}
/* STARTER */
else if (!strncmp("LIGHT", glrenderer, 5) ||
!strncmp("LG1MC", glrenderer, 5)) {
strcpy(buf, "LG");
}
/* NEWPORT */
else if (!strncmp("NEWPORT", glrenderer, 7)) {
strcpy(buf, "NG24");
}
else {
printf( "unexpected GL_RENDERER string\n" );
exit (1);
}
}
/*---- Misc ---------------------------------------------------------------*/
/*
** Get the X pixel value for a 3-component color.
*/
unsigned long utilXPixel(float r, float g, float b, XVisualInfo *vi)
{
unsigned long rmask, gmask, bmask;
unsigned long rmax, gmax, bmax;
int rshift, gshift, bshift;
unsigned long pixel;
if (vi->class != TrueColor && vi->class != DirectColor) {
fprintf( stderr, "PixelOf: visual has wrong class\n");
exit(1);
}
/*
** Count the number of shifts for each component.
*/
rmask = vi->red_mask;
for (rshift=0; !(rmask & 1); rshift++) rmask >>= 1;
gmask = vi->green_mask;
for (gshift=0; !(gmask & 1); gshift++) gmask >>= 1;
bmask = vi->blue_mask;
for (bshift=0; !(bmask & 1); bshift++) bmask >>= 1;
rmax = vi->red_mask >> rshift;
gmax = vi->green_mask >> gshift;
bmax = vi->blue_mask >> bshift;
r = (r >= 1 ? rmax : r*(rmax+1));
g = (g >= 1 ? gmax : g*(gmax+1));
b = (b >= 1 ? bmax : b*(bmax+1));
pixel = (((unsigned long)r << rshift) |
((unsigned long)g << gshift) |
((unsigned long)b << bshift));
return pixel;
}
/*
* Useful for debugging.
*/
void utilCheckError(void)
{
GLenum error = glGetError();
if (error) {
fprintf (stderr, "error found: %x\n", error);
}
}